<template>
  <DetailPanel
    v-if="showDetailPanel"
    :discipline="discipline"
    class="detail-panel"
  />
  <div
    ref="chartContainer"
    class="main-panel"
  ></div>
</template>

<style scoped>
.main-panel {
  width: 100%;
  height: 100%;
  position: relative;
  z-index: 1;
}

.detail-panel {
  z-index: 2;
}
</style>

<script lang="ts">
export default {
  name: 'GraphPanel'
}
</script>

<script lang="ts" setup>
import { useThemeStore } from '@/stores/theme'
import { storeToRefs } from 'pinia'
import { onMounted, onUnmounted, ref, watch } from 'vue'
import * as echarts from 'echarts'
import { getKnowledgeGraphData } from '@/utils/api'
import DetailPanel from '@/components/DetailPanel.vue'
import type { Discipline } from '@/utils/models'

// Store and theme refs
const themeStore = useThemeStore()
const { isDarkMode } = storeToRefs(themeStore)

// Component refs
const chartContainer = ref<HTMLElement | null>(null)
let chart: echarts.ECharts | null = null

// Data refs
const discipline = ref<Discipline>(Object.create({} as Discipline))
const showDetailPanel = ref(false)
const graphData = ref<any>(null)

// Constants
const SIZE_MAP: Record<number, number> = {
  0: 20,
  1: 20,
  2: 15,
  3: 15,
  4: 5
}
const DEFAULT_SIZE = 15

function calculateSymbolSize(level: number | undefined): number {
  if (level === undefined) return DEFAULT_SIZE
  return SIZE_MAP[level] || DEFAULT_SIZE
}

function getChartTheme(isDark: boolean) {
  return {
    backgroundColor: isDark ? '#1a1a1a' : '#ffffff',
    textStyle: {
      color: isDark ? '#ffffff' : '#000000'
    },
    lineStyle: {
      color: isDark ? '#ffffff' : '#000000',
      opacity: 0.5,
      width: 1,
      type: 'solid'
    }
  }
}

function createChartOption(data: any, isDark: boolean) {
  const nodes = data.nodes.map((element: { x: any; y: any; name: string }) => ({
    ...element,
    x: Number(element.x),
    y: Number(element.y),
    symbolSize: calculateSymbolSize(data.data.get(element.name)?.discipline_level),
    label: {
      color: '#fff',
      textBorderWidth: 1,
      textBorderType: 'solid',
      textBorderColor: 'inherit'
    }
  }))

  const theme = getChartTheme(isDark)

  return {
    backgroundColor: theme.backgroundColor,
    series: [
      {
        type: 'graph',
        top: '10%',
        roam: true,
        focusNodeAdjacency: true,
        symbol: 'circle',
        lineStyle: {
          normal: theme.lineStyle
        },
        label: {
          normal: {
            show: true,
            textStyle: {
              ...theme.textStyle,
              fontSize: 8
            }
          }
        },
        data: nodes,
        links: data.links,
        categories: data.categories
      }
    ]
  }
}

function initChartInstance() {
  if (!chartContainer.value || !graphData.value) return

  // Dispose existing chart if it exists
  if (chart) {
    chart.dispose()
  }

  // Initialize new chart
  chart = echarts.init(chartContainer.value)
  const option = createChartOption(graphData.value, isDarkMode.value)
  chart.setOption(option)

  // Handle click events
  chart.on('click', function (params) {
    if (params.dataType === 'node') {
      showDetailPanel.value = true
      discipline.value = graphData.value.data.get(params.name) || discipline.value
    } else {
      showDetailPanel.value = false
    }
  })

  // Handle blank area clicks
  chartContainer.value.addEventListener('click', (event) => {
    const target = event.target as HTMLElement
    if (target === chartContainer.value) {
      showDetailPanel.value = false
    }
  })
}

async function loadData() {
  try {
    graphData.value = await getKnowledgeGraphData()
    initChartInstance()
  } catch (error) {
    console.error('Failed to load graph data:', error)
    // 这里可以添加错误处理逻辑，比如显示错误提示
  }
}

// Handle window resize
function handleResize() {
  if (chart) {
    chart.resize()
  }
}

// Watch for theme changes
watch(isDarkMode, () => {
  if (chart && graphData.value) {
    const option = createChartOption(graphData.value, isDarkMode.value)
    chart.setOption(option)
  }
})

// Lifecycle hooks
onMounted(async () => {
  await loadData()
  window.addEventListener('resize', handleResize)
})

onUnmounted(() => {
  window.removeEventListener('resize', handleResize)
  if (chart) {
    chart.dispose()
    chart = null
  }
})
</script>